<script setup lang="ts" name="GoodsSku">
	import { GoodsInfo, Spec, SpecValue } from '@/types/goods'
	import bwPowerSet from '@/utils/power-set'
	const props = defineProps<{
		goods: GoodsInfo
		skuId?: string
	}>()

	const emit = defineEmits<{
		(e: 'changeSku', skuId: string): void
	}>()

	const changeSelected = (item: Spec, sub: SpecValue) => {
		if (sub.disabled) return
		if (sub.seleceted) {
			sub.seleceted = false
		} else {
			// 排它
			item.values.forEach((sub) => {
				sub.seleceted = false
			})
			sub.seleceted = true
		}
		updateDisabledStatus()

		// 判断是否选中所有规格, 如果选中了所有规格, 将sku的数据传递给父组件
		const selectedSpec = getSelectedSpec().filter(Boolean)
		if (selectedSpec.length === props.goods.specs.length) {
			const key = selectedSpec.join('⭐')
			// 在pathMap中查找
			const [skuId] = pathMap[key]
			// 子传父
			emit('changeSku', skuId)
		} else {
			emit('changeSku', '')
		}
	}

	// 获取路径字典
	const getPathMap = () => {
		const pathMap: { [key: string]: string[] } = {}
		// 1.过滤没有库存的skus
		const skus = props.goods.skus.filter((item) => item.inventory > 0)
		// 2.遍历skus
		skus.forEach((item) => {
			// 3.获取每一个sku的值, 比如蓝色, 中国
			const arr = item.specs.map((sub) => sub.valueName)
			// 4.根据powerSet获取子集组合
			const powerSet = bwPowerSet(arr)
			// 5.遍历子集, 添加到pathMap
			powerSet.forEach((sub) => {
				// 6.拼接key
				const key = sub.join('⭐')
				// 7.判断key在pathMap中是否存在
				if (key in pathMap) {
					pathMap[key].push(item.id)
				} else {
					pathMap[key] = [item.id]
				}
			})
		})
		return pathMap
	}
	const pathMap = getPathMap()

	// 获取选中的spec
	const getSelectedSpec = () => {
		const arr: string[] = []
		props.goods.specs.forEach((item) => {
			const temp = item.values.find((sub) => sub.seleceted)
			arr.push(temp ? temp.name : '')
		})
		return arr
	}

	// 初始化时, 设置默认选中效果
	const initSelectedSpec = () => {
		const sku = props.goods.skus.find((item) => item.id === props.skuId)
		if (sku) {
			props.goods.specs.forEach((item, index) => {
				item.values.forEach((sub) => {
					// 购物车页面 默认选择bug 增加排他
					sub.seleceted = false
					if (sub.name === sku.specs[index].valueName) {
						sub.seleceted = true
					}
				})
			})
		}
	}
	initSelectedSpec()

	// 更新按钮的禁用状态
	const updateDisabledStatus = () => {
		props.goods.specs.forEach((item, index) => {
			// 得到选中的状态 [xxx, yyy, zzz]
			const selectedSpec = getSelectedSpec()
			item.values.forEach((sub) => {
				// [xxx, yyy, zzz] 第二个spec开始, 得到特定的xxx规格, yyy改变
				selectedSpec[index] = sub.name
				const key = selectedSpec.filter(Boolean).join('⭐')
				if (key in pathMap) {
					sub.disabled = false
				} else {
					sub.disabled = true
				}
			})
		})
	}
	updateDisabledStatus()
</script>
<template>
	<div class="goods-sku">
		<dl v-for="item in goods.specs" :key="item.id">
			<dt>{{ item.name }}</dt>
			<dd>
				<!-- id 1369155859933827074 -->
				<template v-for="sub in item.values" :key="sub.id">
					<img
						v-if="sub.picture"
						:src="sub.picture"
						:title="sub.name"
						alt=""
						:class="{ selected: sub.seleceted, disabled: sub.disabled }"
						@click="changeSelected(item, sub)"
					/>
					<span
						v-else
						:class="{ selected: sub.seleceted, disabled: sub.disabled }"
						@click="changeSelected(item, sub)"
						>{{ sub.name }}</span
					>
				</template>
			</dd>
		</dl>
	</div>
</template>

<style scoped lang="less">
	.sku-state-mixin () {
		border: 1px solid #e4e4e4;
		margin-right: 10px;
		cursor: pointer;
		&.selected {
			border-color: @xtxColor;
		}
		&.disabled {
			opacity: 0.6;
			border-style: dashed;
			cursor: not-allowed;
		}
	}
	.goods-sku {
		padding-left: 10px;
		padding-top: 20px;
		dl {
			display: flex;
			padding-bottom: 20px;
			align-items: center;
			dt {
				width: 50px;
				color: #999;
			}
			dd {
				flex: 1;
				color: #666;
				> img {
					width: 50px;
					height: 50px;
					.sku-state-mixin ();
				}
				> span {
					display: inline-block;
					height: 30px;
					line-height: 30px;
					padding: 0 20px;
					margin-top: 5px;
					.sku-state-mixin ();
				}
			}
		}
	}
</style>
